public without sharing class QuoteAboardController {

	public String backId {get; private set;} 
	public String msg {get; private set;} 
	public Boolean isErr {get; private set;} 
	public String dataJson {get; private set;} 
	public String saveJson {get;  set;} 
	public String searchJson {get;  set;} 
	public Boolean isSuccess {get ; private set;}
	private Boolean isNew ; 
    public class ControllerException extends Exception {}
	private  String sealflag;
	private Quote q  ; 
	public String company {get; private set;}
    public String province {get; private set;} 
	private Map<String,DataUtil.SObjectBean> stageObjectMap ; 


    public QuoteAboardController() {
        stageObjectMap = new Map<String,DataUtil.SObjectBean>();
    }
    public void setNil(){
    	dataJson = '{}';
    	saveJson = '[]';
    	searchJson = '{}';
    }
    //设置错误
    private void setError(String message){
    	isErr = true;
      throw new ControllerException(message);

    }

    public void save(){
        msg = '';

        try {


            Map<String,Object> saveMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(saveJson, 'UTF-8'));

        
             Set<String>  prosets = new Set<String>();

            List<QuoteProduct__c>qList =new List<QuoteProduct__c>();
            if(saveMap.containsKey('detail')){
                List<Object> qpList = (List<Object>)saveMap.get('detail');

                Set<Id> prdset = new Set<Id>();
                for(Object o : qpList){
                    Map<String,Object> mo = (Map<String,Object>)o ; 
                    prdset.add(Id.valueOf(DataUtil.getStringValue(mo.get('productId'))));

                }
               Map<Id,Price__c> priceMap = ImportObject.getPriceMap(prdset,company,province);
               System.debug(priceMap);
                

                for(Object o : qpList){
                    Map<String,Object> mo = (Map<String,Object>)o ; 

                    QuoteProduct__c qp= new QuoteProduct__c();
                    qp.Product__c = Id.valueOf(DataUtil.getStringValue(mo.get('productId')));
                    qp.CooperativePrice__c = DataUtil.getDecimalValue(mo.get('coopprice'));
                    qp.PrototypePrice__c= DataUtil.getDecimalValue(mo.get('sampleprice'));
                    qp.BuyingPrice__c = DataUtil.getDecimalValue(mo.get('buyprice'));
                    qp.Remarks__c = DataUtil.getStringValue(mo.get('note'));
                    qp.MarketQuotation__c = DataUtil.getDecimalValue(mo.get('marketprice'));

                    if(qp.MarketQuotation__c == null || qp.MarketQuotation__c == 0)prosets.add(DataUtil.getStringValue(mo.get('productName')));

                    qp.Category0__c = DataUtil.getStringValue(mo.get('cate0'));
                    qp.SerialNo__c = DataUtil.getStringValue(mo.get('serialno'));
                    qp.Spec__c =DataUtil.getStringValue(mo.get('spec'));

                    qp.SalesmanPrice__c = priceMap.containsKey(qp.Product__c) ?priceMap.get(qp.Product__c).SalesmanPrice__c :null ;
                    qp.SalesDirectorPrice__c = priceMap.containsKey(qp.Product__c) ?priceMap.get(qp.Product__c).SalesDirectorPrice__c :null ;
                    qp.SalesManagerPrice__c = priceMap.containsKey(qp.Product__c) ?priceMap.get(qp.Product__c).SalesManagerPrice__c :null ;

                    qList.add(qp);

                }
            }

            if(!prosets.isEmpty())throw new DmlException('以下产品没有海外标准报价(美元):'+String.join(new List<String>(prosets), ','));
            if(qList.size() == 0 )throw new DmlException('没有产品数据!');
               

            SavePoint sp = Database.setSavepoint();
            try {
                System.debug('QuoteAboardController==>'+q);
               upsert q ; 
               if(!isNew)delete [select Id from QuoteProduct__c where Quote__c =:q.Id ];
               for(QuoteProduct__c qp : qList){
                    qp.Quote__c = q.Id; 
               }
               if(qList.size() > 0) insert qList;
               isSuccess = true; 
               backId = q.Id ; 
               msg = '保存成功!';
            }catch (Exception e) {
                Database.rollback(sp);
                
                if(isNew){
                    q.Id = null; 
                }
                throw e ;
            }
            
        }catch (Exception e) {
            msg = '保存失败:'+e.getMessage();

        }
        
    	
    	
    	

    }
    public void init(){
    	backId = System.currentPageReference().getParameters().get('id');
    	q = new Quote();
    	isNew = false; 
    	try {
    	 	if(backId == null) setError('打开页面错误!');
            Opportunity opp = null;
    	 	String oppId = null; 
    	 	if(Id.valueOf(backId).getSObjectType() == Opportunity.SObjectType){

    	 		 opp = [select Id ,Owner.SubCompany__c,Owner.PriceProvince__c,StageName from Opportunity where Id=:backId ];
    	 		company = opp.Owner.SubCompany__c ; 
                province = opp.Owner.PriceProvince__c;
    	 		isNew = true; 
    	 		oppId = opp.Id ; 
    	 		q.OpportunityId = backId; 
                q.Status = '草案中';
                q.RecordTypeId = Utils.getRecordTypeIdByDevNameAndObjName('OverseasQuotation', 'Quote');

    	 	}else if(Id.valueOf(backId).getSObjectType() == Quote.SObjectType){

    	 		q = [select Id,Name ,Status,OpportunityId , Opportunity.Owner.SubCompany__c,Opportunity.Owner.PriceProvince__c from Quote where Id=:backId];
    			company = q.Opportunity.Owner.SubCompany__c;
                province =  q.Opportunity.Owner.PriceProvince__c;

    	 		if(q.Status == '申请中' || q.Status == '已批准' )setError('报价在'+q.Status +'不能修改!');
    	 		oppId = q.OpportunityId ; 
                opp = [select Id ,Owner.SubCompany__c,StageName from Opportunity where Id=:oppId ];

    	 	}else{
    	 		setError('打开页面错误!');
    	 	}

            //当业务机会为 市场管理或者提起或作确认或者失败或者合同签订时，不能新建报价，或者编辑相关业务机会中草案中的报价。
            if(opp.StageName == '合同签订' || opp.StageName == '市场管理' || opp.StageName == '提起合作确认' || opp.StageName == '失败' )setError('业务机会在'+ opp.StageName +'阶段,不能新建/修改报价 ');
         	if(q.Name == null) q.Name ='报价-' + Utils.date2string(System.now(), 'YYYYMMDDHHMMSS'); 
    		sealflag  =  'Y-'+ ImportObject.getPicklistValues('Contract__c','Corpcode__c',false).get(company);   
             Map<String,Object>dataMap = new Map<String,Object>();

    		/* //字段
	    	 Map<String,Set<String>> fieldsmap = getFields();
	    	 //字段详情
	    	 Map<String, List<DataUtil.FieldBean>> fbMap = DataUtil.getFieldsBean(fieldsmap,stageObjectMap);
	    	//字段赋值
	    	 Map<String,List<DataUtil.FieldBean>> fields = DataUtil.setFieldsValue(fbMap,DataUtil.getBaseInfo(fbMap,stageObjectMap) );
	 		dataMap.put('base',fields);
    		dataMap.put('baseObject',DataUtil.getBaseObjectMap(stageObjectMap)); 
*/
    		dataMap.put('searchObject',getSearchObject()); 
    		dataMap.put('intent',getIntentDetail(oppId)); 
    		dataMap.put('detail',getDetails()); 

    		dataJson = EncodingUtil.urlEncode(JSON.serialize(dataMap), 'UTF-8');
    	}catch (Exception e) {
    	    ApexPages.addMessage( new ApexPages.Message(ApexPages.Severity.ERROR ,e.getMessage()));

    	}
    	
    }

    /* private Map<String,Set<String>>  getFields(){
    	Map<String,Set<String>> fieldsMap  = new  Map<String,Set<String>>();
    	
    		DataUtil.SObjectBean sb = new DataUtil.SObjectBean();

    		sb.title ='报价基本信息';
    		sb.objname = 'Quote';
    		sb.stype = DataUtil.getSObjectType('Quote');
    		sb.idvalue = q.Id ;
    		sb.type = 'base';
    		sb.condition = ' where Id =\''+q.Id+'\'';


    		 Set<String>  fields = new Set<String>{'Currency__c'};
    		fieldsMap.put('Quote', fields);
    	
    	return fieldsMap;

    }*/

    private Map<String,List<DataUtil.FieldBean>> getSearchObject(){
    	Map<String,List<DataUtil.FieldBean>> searchMap = new Map<String,List<DataUtil.FieldBean>>();

    	Map<String,DataUtil.FieldBean>proMap = DataUtil.getFieldsInfo(Product__c.SObjecttype, new Set<String>{'ProductName__c','Brand__c','Spec__c','SerialNo__c','Category0__c','Category1__c','NCCode__c'} );
    	searchMap.put('Product__c', proMap.values());
    	return searchMap;
    }


    public void search(){
    	dataJson = '[]';
    	Map<String,Object> searchMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(searchJson,'UTF-8'));

    	String sql = ' select Id ,ProductName__c ,SerialNo__c ,Model__c, Brand__c ,Spec__c,Category0__c,NCCode__c ,Category1__c ,SealCompany__c from Product__c where   Category0__c !=\'仪器\' and (Overseasproducts__c  = true  or Brand__c in '+MaccuraBrandUtil.getMaccuraInStr()+ ') ';
    	
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('ProductName__c'))) == false) sql += ' and ProductName__c like \'%'+DataUtil.getStringValue(searchMap.get('ProductName__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Brand__c'))) == false) sql += ' and Brand__c like \'%'+DataUtil.getStringValue(searchMap.get('Brand__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Spec__c'))) == false) sql += ' and Spec__c like \'%'+DataUtil.getStringValue(searchMap.get('Spec__c'))+'%\' ';

    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('SerialNo__c'))) == false) sql += ' and SerialNo__c like \'%'+DataUtil.getStringValue(searchMap.get('SerialNo__c'))+'%\' ';
 
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category0__c'))) == false) sql += ' and Category0__c like \'%'+DataUtil.getStringValue(searchMap.get('Category0__c'))+'%\' ';
        if(String.isBlank(DataUtil.getStringValue(searchMap.get('Category1__c'))) == false) sql += ' and Category1__c like \'%'+DataUtil.getStringValue(searchMap.get('Category1__c'))+'%\' ';
    	if(String.isBlank(DataUtil.getStringValue(searchMap.get('NCCode__c'))) == false) sql += ' and NCCode__c like \'%'+DataUtil.getStringValue(searchMap.get('NCCode__c'))+'%\' ';

    	sql += ' limit 200 ';
        System.debug('QuoteAboardController=>'+sql);
    	List<QuoteBean>  tmp = new  List<QuoteBean>();
    	Map<Id,Product__c > pMap  = new Map<Id,Product__c>();
    	for(Product__c p: Database.query(sql)){
            if(p.SealCompany__c != null && p.SealCompany__c.contains(sealflag)) continue; 
			pMap.put(p.Id , p);
    	}
   		Map<Id,Price__c> prMap = ImportObject.getPriceMap(pMap.keySet(), company,province);
   		for(Product__c p : pMap.values()){
   			tmp.add(new QuoteBean(p,prMap.get(p.Id)));
   		}
    	dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp), 'UTF-8');

    }

    //获取意向产品
    private List<QuoteBean> getIntentDetail(String opp_id ){
    	List<QuoteBean>  tmp = new  List<QuoteBean>();
    	Set<Id > pset = new Set<Id >();

    	List<IntentProduct__c>ipList = [select Id ,Product__c ,Product__r.Category1__c,Product__r.NCCode__c,
			Product__r.ProductName__c,Product__r.Category0__c,Product__r.Brand__c,Product__r.Model__c,
			Product__r.Spec__c,Product__r.SerialNo__c  from IntentProduct__c where 
			Opportunity__c =:opp_id and Product__r.Category0__c = '仪器'];

		for(IntentProduct__c ip :ipList){
			pset.add(ip.Product__c);
		}

   		Map<Id,Price__c> prMap = ImportObject.getPriceMap(pset, company,province);
   		for(IntentProduct__c ip :ipList){
   			tmp.add(new QuoteBean(ip,prMap.get(ip.Product__c)));

		}
    	
    	return tmp;
     
    }
     @RemoteAction
    public static List<QuoteBean>  matchProduct(List<String> nccodes,String company ,String province  ){
    	List<QuoteBean> tmp = new List<QuoteBean>();
    	
    	String	sealflag  =  'Y-'+ ImportObject.getPicklistValues('Contract__c','Corpcode__c',false).get(company);   
    	Map<Id,Product__c > pMap  = new Map<Id,Product__c>();
    	for(Product__c p : [select Id,ProductName__c ,SerialNo__c ,SealCompany__c,Model__c, Brand__c ,Spec__c,Category0__c,NCCode__c,Category1__c 
    	 from Product__c where NCCode__c in: nccodes and (Overseasproducts__c  = true or Brand__c in: MaccuraBrandUtil.maccura) ]){
            if(p.SealCompany__c != null && p.SealCompany__c.contains(sealflag)) continue; 
			pMap.put(p.Id , p);
    	}

   		Map<Id,Price__c> prMap = ImportObject.getPriceMap(pMap.keySet(), company,province);
   		for(Product__c p : pMap.values()){
            if(!prMap.containsKey(p.Id))continue;
            tmp.add(new QuoteBean(p,prMap.get(p.Id)));
   		}
    	return tmp; 
    }

    ////获取报价产品
    private List<QuoteBean> getDetails( ){
         List<QuoteBean>  tmp = new  List<QuoteBean>();
    	if(!isNew){
    		
            tmp = getQuoteBean(q.Id);
    	}else{
           List<Quote> qLi =  [select Id from Quote where OpportunityId=:backId and Status='已批准' Order by Createddate desc limit 1];
           if(qLi.size() >0 ) tmp = getQuoteBean(qLi[0].Id);
        }
    	return tmp ; 
    }
    private List<QuoteBean> getQuoteBean(String qid ){
                List<QuoteBean>  tmp = new  List<QuoteBean>();

            Set<Id > pset = new Set<Id >();
            List<QuoteProduct__c> qList = [select Id, Product__c , Product__r.Category1__c,Product__r.NCCode__c,
            Product__r.ProductName__c,Product__r.Category0__c,Product__r.Brand__c,Product__r.Model__c,
            Product__r.Spec__c,Product__r.SerialNo__c , CooperativePrice__c,PrototypePrice__c,
            BuyingPrice__c, Remarks__c from QuoteProduct__c where Quote__c =:qid ];

            for(QuoteProduct__c ip :qList){
                pset.add(ip.Product__c);
            }

            Map<Id,Price__c> prMap = ImportObject.getPriceMap(pset, company,province);
            for(QuoteProduct__c ip :qList){
                tmp.add(new QuoteBean(ip,prMap.get(ip.Product__c)));


            }
            return tmp;
    }
     public class QuoteBean {
    	public String productName ;
    	public String productId ;
    	public String cate0;
    	public String cate1 ;
    	public String spec; 
    	public String serialno ;
    	public String brand ;
    	public String nccode ; 
    	public Decimal marketprice; 
    	public Decimal marketpriceCNY; 
    	public Decimal coopprice ; 
    	public Decimal cooppriceCNY; 
    	public Decimal sampleprice ; 
    	public Decimal samplepriceCNY; 
    	public Decimal discount ; 
    	public Decimal buyprice ; 
    	public Decimal buypriceCHY ; 
    	public String note ; 
    	public String model; 
        public Boolean hasprice ; 

    	public QuoteBean(IntentProduct__c ip ,Price__c pr ){

    		productName = ip.Product__r.ProductName__c;
    		productId = ip.Product__c;
    		brand = ip.Product__r.Brand__c; 
    		serialno = ip.Product__r.SerialNo__c; 
    		cate0 = ip.Product__r.Category0__c;
    		cate1 = ip.Product__r.Category1__c;
    		spec = ip.Product__r.Spec__c;
    		model = ip.Product__r.Model__c;
    		nccode = ip.Product__r.NCCode__c;
    		if(pr != null ) marketprice = pr.MarketPriceUSD__c; 
            hasprice = pr != null; 
    	}

    	public QuoteBean(Product__c ip ,Price__c pr ){

    		productName = ip.ProductName__c;
    		productId = ip.Id ;
    		brand = ip.Brand__c; 
    		serialno = ip.SerialNo__c; 
    		cate0 = ip.Category0__c;
    		cate1 = ip.Category1__c;
    		spec = ip.Spec__c;
    		model = ip.Model__c;
    		nccode = ip.NCCode__c;

    		if(pr != null ) marketprice = pr.MarketPriceUSD__c; 
             hasprice = pr != null; 

    	}

    	public QuoteBean(QuoteProduct__c qp , Price__c pr ){

    		productName = qp.Product__r.ProductName__c;
    		productId = qp.Product__c;
    		brand = qp.Product__r.Brand__c; 
    		serialno = qp.Product__r.SerialNo__c; 
    		cate0 = qp.Product__r.Category0__c;
    		cate1 = qp.Product__r.Category1__c;
    		spec = qp.Product__r.Spec__c;
    		model = qp.Product__r.Model__c;
			nccode = qp.Product__r.NCCode__c;
    		if(pr != null ) marketprice = pr.MarketPriceUSD__c; 
            hasprice = pr != null ; 
    		coopprice = qp.CooperativePrice__c;
    		sampleprice = qp.PrototypePrice__c;
    		buyprice = qp.BuyingPrice__c; 

    		note = qp.Remarks__c;  

    	}
    }

}